/**
 * \file grille.h
 * \version 0.3
 *
 * Contient les prototypes des fonctions qui gèrent l'affichage de la grille de sudoku et le déplacement dans celle-ci
 */

#ifndef GRILLE__H__
#define GRILLE__H__

#include <stdlib.h>
#include <tigcclib.h>
#include "constantes.h"
#include "macros.h"
#include "ti.h"

#include "grids.h"

#define _GNU_SOURCE

typedef struct grille* grille;

typedef enum mode {EASY, MEDIUM, HARD, EVIL} mode;

/**
 * \brief Crée une grille de n cases qui contiennent toutes la valeur v
 * \param n Nombre de cases à allouer
 * \param v Valeur par défaut de la case
 * \return un tableau de char
 */
char* tableInit(unsigned char n, char v);

/**
 * \brief Remplis un tableau t par une valeur v
 * \param t un tableau
 * \param n sa taille
 * \param v une valeur
 */
void tableFill(char* t, unsigned char n, char v);

/**
 * \brief Alloue la mémoire nécessaire pour une grille de sudoku normale
 * \return une grille de 81 cases qui valent toutes 0
 */
grille Gnew();

/**
 * \brief Vide la grille
 * \param g Grille de jeu
 */
void Grestart(grille g);

/**
 * \brief Reset la grille (garde les cases fixées)
 * \param g Grille de jeu
 */
void Greset(grille g);

/**
 * \brief Charge une grille de jeu à partir d'un tableau
 * \param g Grille de jeu
 * \param t tableau contenant la grille a charger
 */
void Gload(grille g, unsigned char* t);

/**
 * \brief Libère la mémoire occupée par une grille
 * \param g Grille à supprimer
 * \return void
 */
void Gfree(grille g);

/**
 * \brief Déplace la position actuelle sur la grille
 */
void Gmove(grille g, direction d);

/**
 * \brief Fixe toutes les cases non vides de la grille
 * \param g Grille de jeu
 */
void GfixGrid(grille g);

/**
 * \brief Mets à jour les valeurs du tableau filled
 * \param g Grille de jeu
 * \param decr le nombre a décrémenter
 * \param incr le nombre à incrémenter
 */
void Gfilled(grille g, unsigned char decr, unsigned char incr);

/**
 * \brief Mets toutes les cases non fixées à 0
 * \param g Grille de jeu
 */
void GresetNotFixedBoxes(grille g);

/**
 * \brief Abscisse de la case actuelle
 * \param g Grille de jeu
 * \return Abscisse de la case actuelle
 */
unsigned char GgetPosX(grille g);

/**
 * \brief Ordonnée de la case actuelle
 * \param g Grille de jeu
 * \return Ordonnée de la case actuelle
 */
unsigned char GgetPosY(grille g);

/**
 * \brief Retourne l'index correspondant aux coordonées (x,y)
 * \param x Abscisse
 * \param y Ordonnée
 * \return index de la case (x,y)
 */
unsigned char Gindex(unsigned char x, unsigned char y);

/**
 * \brief Retourne le nombre de la case (x,y)
 * \param g Grille de jeu
 * \param x Abscisse de la case
 * \param y Ordonnée de la case
 * \return nombre de la case (x,y)
 */
unsigned char GgetNumber(grille g, unsigned char x, unsigned char y);

/**
 * \brief Retourne le nombre de la case actuelle
 * \param g Grille de jeu
 * \return Nombre de la case actuelle
 */
unsigned char GgetCurrentNumber(grille g);

/**
 * \brief Retourne le nombre de la case d'index i
 * \param g Grille de jeu
 * \param i index
 * \return le nombre de la case d'index i
 */
unsigned char GgetNumberIndex(grille g, unsigned char i);

/**
 * \brief Pour savoir si la case d'index i est fixée
 * \param g Grille de jeu
 * \param i index
 * \return 1 si la case est fixée, 0 sinon
 */
unsigned char GgetFixedIndex(grille g, unsigned char i);

/**
 * \brief Retourne une case du tableau filled qui contient l'état de remplissage des cases de la grille
 * \param g Grille de jeu
 * \param i index
 * \return nombre de 'i' déjà trouvés
 */
unsigned char GgetFilled(grille g, unsigned char i);

/**
 * \brief Remplis la case (x,y) avec le nombre n
 * \param g Grille de jeu
 * \param x Abscisse de la case
 * \param y Ordonnée de la case
 * \param n nombre à insérer
 */
void GsetNumber(grille g, unsigned char x, unsigned char y, unsigned char n);

/**
 * \brief Remplis la case actuelle par le nombre n
 * \param g Grille de jeu
 * \param n nombre à insérer
 */
void GsetCurrentNumber(grille g, unsigned char n);

/**
 * \brief Remplis la case d'index i avec le nombre n
 * \param g Grille de jeu
 * \param i index de la case
 * \param n nombre à insérer
 */
void GsetNumberIndex(grille g, unsigned char i, unsigned char n);

/**
 * \brief Remplis la case actuelle par le nombre n si c'est autorisé
 * \param g Grille de jeu
 * \param n nombre à insérer
 * \return 1 si l'insertion est autorisé et à été effectuée, 0 sinon
 */
char GtryToSetCurrentNumber(grille g, unsigned char n);

/**
 * \brief Affiche la grille de jeu
 * \param g Grille de jeu
 */
void Gdisplay(grille g);

/**
 * \brief Retourne l'abscisse en pixels de la case d'abscisse x
 * \param x Abscisse de la case
 * \return abscisse en pixels
 */
unsigned char GgetXBox(unsigned char x);

/**
 * \brief Retourne l'ordonnée en pixels de la case d'ordonnée x
 * \param x Ordonnée de la case
 * \return ordonnée en pixels
 */
unsigned char GgetYBox(unsigned char y);

/**
 * \brief Affiche le nombre de la case (x,y)
 * \param g Grille de jeu
 * \param x Abscisse de la case
 * \param y Ordonnée de la case
 */
void GdisplayNumber(grille g, unsigned char x, unsigned char y);

/**
 * \brief Affiche tous les nombres de la grille
 * \param g Grille de jeu
 */
void GdisplayAllNumbers(grille g);

/**
 * \brief Affiche la case courante (grosse bordure)
 * \param g Grille de jeu
 */
void GgridCurrentBox(grille g);

/**
 * \brief Vérifie si la grille est remplie
 * \param g Grille de jeu
 * Cette fonction n'effectue aucune vérification du point de vue des règles du sudoku.
 * Elle ne vérifie que si il ne reste plus de 0 dans la grille.
 */
unsigned char GisOver(grille g);

/**
 * \brief Change le mode de jeu pour 'm'
 * \param g Grille de jeu
 * \param m nouveau mode
 */
void GchangeMode(grille g, mode m);

/**
 * \brief Passe à la difficulté suivante
 * \param g Grille de jeu
 */
void GnextMode(grille g);

/**
 * \brief Retourne une chaîne de caractère décrivant la difficulté
 * \param g Grille de jeu
 */
char* GgetMode(grille g);

#endif

